package suncertify.network;

import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.Vector;

import suncertify.db.Data;
import suncertify.db.DuplicateKeyException;
import suncertify.db.RecordNotFoundException;
import suncertify.db.Room;
import suncertify.ui.Subscriber;

/**
 * A wrapper class for the <code>Data</code> class.  In order to communicate with the 
 * database through a network, the same methods must be available, along with some extra
 * 'server mode' specific methods.  These extra methods are only called when the application
 * is running in 'server mode'.
 * @author Paul Wilhelm
 *
 */
public class ServerImpl implements ServerInterface{
	
	private Data d;						
	private int port;
	private static ServerImpl impl;			//Must be static to keep the exported object alive
	
	/**
	 * Constructor.  Creates a new <code>ServerImpl</code> class and assigns a port to it.
	 * @param port - The port to be used with which to connect to the server.
	 */
	public ServerImpl(int port){
		this.port = port;
		d = Data.getInstance();
	}
	
	/**
	 * {@inheritDoc}
	 */
	public int create(String[] data) throws DuplicateKeyException, RemoteException {
		return d.create(data);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void delete(int recNo) throws RecordNotFoundException, RemoteException {
		d.delete(recNo);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public int[] find(String[] criteria) throws RecordNotFoundException, RemoteException {
		return d.find(criteria);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public boolean isLocked(int recNo) throws RecordNotFoundException, RemoteException {
		return d.isLocked(recNo);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void lock(int recNo) throws RecordNotFoundException, RemoteException {
		d.lock(recNo);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public String[] read(int recNo) throws RecordNotFoundException, RemoteException {
		return d.read(recNo);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void unlock(int recNo) throws RecordNotFoundException, RemoteException {
		d.unlock(recNo);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void update(int recNo, String[] data) throws RecordNotFoundException, RemoteException {
		d.update(recNo, data);
		d.notifySubscriptions();
	}
	
	/**
	 * Starts the application running in server mode.  At this point, 
	 * the application is ready to listen to incoming requests.
	 * @throws RemoteException
	 */
	public void startServer() throws RemoteException{
		impl = new ServerImpl(port);
		ServerInterface stub = (ServerInterface) UnicastRemoteObject.exportObject(impl,0);
		Registry registry = LocateRegistry.createRegistry(port);
		registry.rebind("urlyServer", stub);
		System.out.println("Server Running on Port " + port);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public Vector<Room> getAllRooms() throws IOException, RemoteException {
		return d.getAllRooms();
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void notifySubscriptions() throws RemoteException {
		d.notifySubscriptions();
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void subscribe(Subscriber s) throws RemoteException {
		d.subscribe(s);	
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void unSubscribe(Subscriber s) throws RemoteException {
		d.unSubscribe(s);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void setRequestingName(String name){
		d.setRequestingName(name);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void setRequestingLocation(String location){
		d.setRequestingLocation(location);
	}
	
	
	
	
}
